﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Xml;

namespace XMK.Utils
{
    /// <summary>
    /// XML序列化帮助类
    /// </summary>
    public sealed class XmlHelper
    {
        /// <summary>
        /// 序列化对象成字符串
        /// </summary>
        /// <param name="obj">实例化的对象</param>
        /// <returns>字符串格式的对象</returns>
        public static string SerializerToString(object obj)
        {
            if(obj == null || obj == DBNull.Value)
                throw new Exception("参数为空");
            using (StringWriter sw = new StringWriter())
            {
                XmlSerializer xz = new XmlSerializer(obj.GetType());
                xz.Serialize(sw, obj);
                return sw.ToString();
            }
        }
        /// <summary>
        /// 将对象按照指定类型序列化
        /// </summary>
        /// <param name="obj">需序列化的对象</param>
        /// <param name="t">序列化类型</param>
        /// <returns></returns>
        public static string SerializerToString(object obj,Type t)
        {
            return SerializerToString(obj, new Type[] { t });
        }
        /// <summary>
        /// 序列化对象成字符串(如果对象为数组，则需要指定数组对象的各种类型
        /// </summary>
        /// <param name="obj">需序列化的对象</param>
        /// <param name="types">类型数组</param>
        /// <returns></returns>
        public static string SerializerToString(object obj,Type[] types)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                XmlTextWriter sw = new XmlTextWriter(ms, Encoding.UTF8);
                XmlSerializer xz = new XmlSerializer(obj.GetType(), types);
                //XmlSerializerNamespaces np = new XmlSerializerNamespaces();
                //np.Add(string.Empty, string.Empty);
                sw.Formatting = Formatting.Indented;
                xz.Serialize(sw, obj);
                string strReturn = Encoding.UTF8.GetString(ms.ToArray());
                ms.Close();
                sw.Close();
                return strReturn;
            }
        }

        /// <summary>
        /// 将xml文件的内容反序列化成对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="fileName">xml文件路径文件名，形如：C:\test.xml</param>
        /// <returns>对象</returns>
        public static T Deserialize<T>(string fileName)
        {
            using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                XmlSerializer xs = new XmlSerializer(typeof(T));
                T obj = (T)xs.Deserialize(stream);
                stream.Close();
                return obj;
            }
        }

        /// <summary>
        /// 将字符串反序列化成对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="contents">对象序列化后的Xml字符串</param>
        /// <returns>对象值</returns>
        public static T DeserializeFromString<T>(string contents)
        {
            using (StringReader sr = new StringReader(contents))
            {
                XmlSerializer mySerializer = new XmlSerializer(typeof(T));
                T myObject = (T)mySerializer.Deserialize(sr);
                return myObject;
            }
        }
        /// <summary>
        /// 字符串反序列化为对象
        /// </summary>
        /// <typeparam name="T">转化后的对象</typeparam>
        /// <param name="contents">需要反序列化的字符串</param>
        /// <param name="types">对象类型数组</param>
        /// <returns>反序列化后的对象</returns>
        public static T DeserializeFromString<T>(string contents, Type[] types)
        {
            using (StringReader sr = new StringReader(contents))
            {
                XmlSerializer mySerializer = new XmlSerializer(typeof(T), types);
                T myObject = (T)mySerializer.Deserialize(sr);
                return myObject;
            }
        }
        /// <summary>
        /// 字符串反序列化为对象
        /// </summary>
        /// <typeparam name="T">转化后的对象</typeparam>
        /// <param name="contents">需要反序列化的字符串</param>
        /// <param name="type">对象类型</param>
        /// <returns>反序列化后的对象</returns>
        public static T DeserializeFromString<T>(string contents, Type type)
        {
            return DeserializeFromString<T>(contents, new Type[] { type });
        }
    }
}
